using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;

namespace BoringTodo
{
    public partial class DataRecoveryForm : Form
    {
        private readonly List<string> backupDirectories;
        private ListView listViewBackups;
        private Button btnRestore;
        private Button btnCancel;
        private Label lblTitle;

        public DataRecoveryForm()
        {
            InitializeComponent();
            
            // 尝试多个可能的备份目录位置
            backupDirectories = new List<string>
            {
                Path.Combine(Application.StartupPath, "Backups"),
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "boringtodo", "备份"),
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "BoringTodo", "Backups"),
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "BoringTodo", "备份")
            };
            
            LoadBackups();
        }

        private void InitializeComponent()
        {
            this.listViewBackups = new ListView();
            this.btnRestore = new Button();
            this.btnCancel = new Button();
            this.lblTitle = new Label();
            this.SuspendLayout();
            // 
            // listViewBackups
            // 
            this.listViewBackups.FullRowSelect = true;
            this.listViewBackups.GridLines = true;
            this.listViewBackups.Location = new Point(12, 40);
            this.listViewBackups.Name = "listViewBackups";
            this.listViewBackups.Size = new Size(560, 300);
            this.listViewBackups.TabIndex = 0;
            this.listViewBackups.UseCompatibleStateImageBehavior = false;
            this.listViewBackups.View = View.Details;
            this.listViewBackups.Columns.Add("备份时间", 200);
            this.listViewBackups.Columns.Add("文件大小", 100);
            this.listViewBackups.Columns.Add("备份类型", 200);
            // 
            // btnRestore
            // 
            this.btnRestore.Location = new Point(397, 346);
            this.btnRestore.Name = "btnRestore";
            this.btnRestore.Size = new Size(85, 30);
            this.btnRestore.TabIndex = 1;
            this.btnRestore.Text = "恢复";
            this.btnRestore.UseVisualStyleBackColor = true;
            this.btnRestore.Click += new EventHandler(this.btnRestore_Click);
            // 
            // btnCancel
            // 
            this.btnCancel.Location = new Point(488, 346);
            this.btnCancel.Name = "btnCancel";
            this.btnCancel.Size = new Size(85, 30);
            this.btnCancel.TabIndex = 2;
            this.btnCancel.Text = "取消";
            this.btnCancel.UseVisualStyleBackColor = true;
            this.btnCancel.Click += new EventHandler(this.btnCancel_Click);
            // 
            // lblTitle
            // 
            this.lblTitle.AutoSize = true;
            this.lblTitle.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Bold);
            this.lblTitle.Location = new Point(12, 9);
            this.lblTitle.Name = "lblTitle";
            this.lblTitle.Size = new Size(74, 21);
            this.lblTitle.TabIndex = 3;
            this.lblTitle.Text = "数据恢复";
            // 
            // DataRecoveryForm
            // 
            this.ClientSize = new Size(584, 388);
            this.Controls.Add(this.lblTitle);
            this.Controls.Add(this.btnCancel);
            this.Controls.Add(this.btnRestore);
            this.Controls.Add(this.listViewBackups);
            this.FormBorderStyle = FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "DataRecoveryForm";
            this.StartPosition = FormStartPosition.CenterParent;
            this.Text = "数据恢复";
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void LoadBackups()
        {
            bool foundBackups = false;
            
            // 尝试从多个可能的备份目录加载文件
            foreach (var directory in backupDirectories)
            {
                if (Directory.Exists(directory))
                {
                    var backupFiles = Directory.GetFiles(directory, "*.json")
                        .Select(f => new FileInfo(f))
                        .OrderByDescending(f => f.LastWriteTime);
                    
                    foreach (var file in backupFiles)
                    {
                        var item = new ListViewItem(file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss"));
                        item.SubItems.Add(FormatFileSize(file.Length));
                        item.SubItems.Add(Path.GetFileNameWithoutExtension(file.Name));
                        item.Tag = file.FullName;
                        listViewBackups.Items.Add(item);
                        foundBackups = true;
                    }
                }
            }
            
            if (!foundBackups)
            {
                MessageBox.Show("未找到备份文件。请确保备份文件存在，或者检查'我的文档\\boringtodo\\备份'目录。", 
                    "没有找到备份", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private string FormatFileSize(long bytes)
        {
            string[] sizes = { "B", "KB", "MB", "GB" };
            int order = 0;
            double size = bytes;
            while (size >= 1024 && order < sizes.Length - 1)
            {
                order++;
                size /= 1024;
            }
            return $"{size:0.##} {sizes[order]}";
        }

        private void btnRestore_Click(object sender, EventArgs e)
        {
            if (listViewBackups.SelectedItems.Count == 0)
            {
                MessageBox.Show("请选择要恢复的备份文件。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            var selectedFile = listViewBackups.SelectedItems[0].Tag.ToString();
            var fileName = Path.GetFileNameWithoutExtension(selectedFile);
            
            if (MessageBox.Show($"确定要恢复选中的备份文件 '{fileName}' 吗？当前数据将被覆盖。", "确认恢复",
                MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                try
                {
                    // 检查源文件是否存在且可以读取
                    if (!File.Exists(selectedFile))
                    {
                        MessageBox.Show($"无法找到备份文件: {selectedFile}", "文件错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    
                    // 先验证源文件的内容
                    string sourceContent;
                    try {
                        sourceContent = File.ReadAllText(selectedFile);
                        if (string.IsNullOrWhiteSpace(sourceContent))
                        {
                            MessageBox.Show("所选的备份文件内容为空！", "空文件", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                        
                        // 尝试验证JSON格式
                        try
                        {
                            JArray.Parse(sourceContent);
                            Logger.Log($"备份文件内容验证成功: {selectedFile}", LogLevel.Info);
                        }
                        catch (Exception jsonEx)
                        {
                            Logger.LogError($"备份文件不是有效的JSON格式: {selectedFile}", jsonEx);
                            if (MessageBox.Show($"所选备份文件不是有效的JSON格式，可能会导致恢复失败。是否继续？\n\n错误: {jsonEx.Message}", 
                                "格式错误", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
                            {
                                return;
                            }
                        }
                    }
                    catch (Exception readEx)
                    {
                        Logger.LogError($"读取备份文件失败: {selectedFile}", readEx);
                        MessageBox.Show($"无法读取备份文件: {readEx.Message}", "读取错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    
                    // 确定主数据目录 - 先使用"我的文档"下的标准位置
                    string myDocsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    string primaryDataDir = Path.Combine(myDocsPath, "BoringTodo");
                    
                    // 如果在"我的文档"下找不到，则尝试使用应用程序目录
                    if (!Directory.Exists(primaryDataDir))
                    {
                        primaryDataDir = Application.StartupPath;
                    }
                    
                    // 检查文件名以确定恢复类型
                    bool isCompletedTasks = fileName.Contains("completed");
                    
                    // 获取目标文件名
                    string targetFileName = isCompletedTasks ? "completed_tasks.json" : "tasks.json";
                    
                    // 创建多个可能的目标位置列表
                    List<string> possibleTargetPaths = new List<string>
                    {
                        // 我的文档下的位置
                        Path.Combine(myDocsPath, "BoringTodo", targetFileName),
                        // 应用程序目录下的位置
                        Path.Combine(Application.StartupPath, targetFileName),
                        // 我的文档下带Data子目录的位置
                        Path.Combine(myDocsPath, "BoringTodo", "Data", targetFileName),
                        // 应用程序目录下带Data子目录的位置
                        Path.Combine(Application.StartupPath, "Data", targetFileName)
                    };
                    
                    // 尝试找到已存在的目标文件（用于确定恢复位置）
                    string targetFile = null;
                    foreach (var path in possibleTargetPaths)
                    {
                        if (File.Exists(path))
                        {
                            targetFile = path;
                            Logger.Log($"找到现有数据文件: {path}", LogLevel.Info);
                            break;
                        }
                    }
                    
                    // 如果找不到现有文件，则使用默认位置
                    if (string.IsNullOrEmpty(targetFile))
                    {
                        // 默认使用我的文档位置
                        targetFile = Path.Combine(myDocsPath, "BoringTodo", targetFileName);
                        Logger.Log($"未找到现有数据文件，将使用默认位置: {targetFile}", LogLevel.Info);
                        
                        // 确保目标目录存在
                        string targetDir = Path.GetDirectoryName(targetFile);
                        if (!Directory.Exists(targetDir))
                        {
                            Directory.CreateDirectory(targetDir);
                            Logger.Log($"创建目标目录: {targetDir}", LogLevel.Info);
                        }
                    }
                    
                    // 备份当前数据文件
                    if (File.Exists(targetFile))
                    {
                        string backupDir = Path.Combine(Path.GetDirectoryName(targetFile), "备份");
                        if (!Directory.Exists(backupDir))
                        {
                            Directory.CreateDirectory(backupDir);
                        }
                        
                        string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
                        string backupFile = Path.Combine(backupDir, 
                            Path.GetFileNameWithoutExtension(targetFile) + "_" + timestamp + ".json");
                        
                        try
                        {
                            File.Copy(targetFile, backupFile, true);
                            Logger.Log($"已备份当前数据文件到: {backupFile}", LogLevel.Info);
                        }
                        catch (Exception backupEx)
                        {
                            Logger.LogError($"备份当前数据文件失败: {targetFile}", backupEx);
                            if (MessageBox.Show($"无法备份当前数据文件，继续恢复可能导致数据丢失。是否继续？\n\n错误: {backupEx.Message}", 
                                "备份错误", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
                            {
                                return;
                            }
                        }
                    }
                    
                    // 使用流复制方式确保文件正确写入
                    try
                    {
                        // 删除目标文件以确保完全重写
                        if (File.Exists(targetFile))
                        {
                            File.SetAttributes(targetFile, FileAttributes.Normal);
                            File.Delete(targetFile);
                            Logger.Log($"删除现有目标文件: {targetFile}", LogLevel.Info);
                        }
                        
                        // 使用直接文本写入方式复制内容
                        File.WriteAllText(targetFile, sourceContent);
                        
                        // 验证写入成功
                        if (File.Exists(targetFile))
                        {
                            string verifyContent = File.ReadAllText(targetFile);
                            if (verifyContent == sourceContent)
                            {
                                Logger.Log($"数据恢复成功，验证通过: {targetFile}", LogLevel.Info);
                            }
                            else
                            {
                                Logger.LogError($"数据写入验证失败，内容不匹配: {targetFile}", null);
                                MessageBox.Show("数据写入验证失败，内容不匹配。请尝试重新恢复或检查文件权限。", 
                                    "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                return;
                            }
                        }
                        else
                        {
                            Logger.LogError($"写入目标文件后无法找到文件: {targetFile}", null);
                            MessageBox.Show($"写入目标文件后无法找到文件: {targetFile}", 
                                "文件错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }
                    }
                    catch (Exception writeEx)
                    {
                        Logger.LogError($"写入目标文件失败: {targetFile}", writeEx);
                        MessageBox.Show($"写入目标文件失败: {writeEx.Message}\n\n请检查文件权限或尝试以管理员身份运行程序。", 
                            "写入错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    
                    // 显示成功信息
                    MessageBox.Show($"数据恢复成功！\n" +
                        $"源文件: {fileName}\n" +
                        $"目标文件: {targetFile}\n\n" +
                        $"文件大小: {new FileInfo(targetFile).Length} 字节", 
                        "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    
                    DialogResult = DialogResult.OK;
                    Close();
                }
                catch (Exception ex)
                {
                    Logger.LogError($"恢复数据时发生错误：{ex.Message}", ex);
                    MessageBox.Show($"恢复数据时发生错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            Close();
        }
    }
} 